﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using N2.Web;
using N2.Web.Mvc;
using Dinamico.Models;
using N2.Collections;
using System.Text;
using N2;
using System.Text.RegularExpressions;
using System.Web.Security;
using N2.Engine.Globalization;
using N2.Definitions;
using N2.Persistence.Search;

namespace Dinamico.Controllers
{
    [Controls(typeof(StartPage))]
    public class StartPageController : ContentController<StartPage>
    {
        public ActionResult NotFound()
        {
            var closestMatch = Content.Traverse.Path(Request.AppRelativeCurrentExecutionFilePath.Trim('~', '/')).StopItem;

            var startPage = Content.Traverse.ClosestStartPage(closestMatch);
            var urlText = Request.AppRelativeCurrentExecutionFilePath.Trim('~', '/').Replace('/', ' ');
            var similarPages = GetSearchResults(startPage, urlText, 10).ToList();

            ControllerContext.RouteData.ApplyCurrentItem(new ContentPage { Parent = startPage }, null);
            Response.TrySkipIisCustomErrors = true;
            Response.Status = "404 Not Found";

            return View(similarPages);
        }

        [ContentOutputCache]
        public ActionResult SiteMap()
        {
            var start = this.Content.Traverse.StartPage;
            string content = Tree.From(start)
                .Filters(N2.Content.Is.Accessible())
                .ExcludeRoot(true).ToString();
            return Content("<ul>"
                + "<li>" + Link.To(start) + "</li>"
                + content + "</ul>");
        }

        const int take = 50;
        public ActionResult Search(string q)
        {
            

            if (string.IsNullOrWhiteSpace(q))
                return Content("<ul><li>tekst jest wymagany</li></ul>");

            //var hits = GetSearchResults(CurrentPage ?? this.Content.Traverse.StartPage, q, 50);
            var hits = GetSearchResultsArticles(q).Take(take);
            StringBuilder results = new StringBuilder();
            foreach (var hit in hits)
            {
                results.Append("<li>").Append(Link.To(hit.Parent)).Append("</li>");
            }
            var hits2   = GetSearchResults(CurrentPage ?? this.Content.Traverse.StartPage, q, take - hits.Count());
            foreach (var hit in hits2)
            {
                results.Append("<li>").Append(Link.To(hit)).Append("</li>");
            }

            if (results.Length == 0)
                return Content("<ul><li>brak wyników</li></ul>");

            return Content("<ul>" + results + "</ul>");
        }

        private IEnumerable<ContentItem> GetSearchResults(ContentItem root, string text, int take)
        {
            try
            {
                var query = Query.For(text).Below(root).ReadableBy(User, Roles.GetRolesForUser).Except(Query.For(typeof(ISystemNode)));
                var hits = Engine.Resolve<ITextSearcher>().Search(query).Hits.Select(h => h.Content);
                return hits;
            }
            catch (Exception ee) {

                return new List<ContentItem>();
            }
        }

        const int take200 = 200;
        private IEnumerable<ContentItem> GetSearchResultsArticles(string text)
        {
            IEnumerable<PartProductGoogleModel> cmlist = N2.Find.Items.Where
                .Type.Eq(typeof(PartProductGoogleModel))
                .And.State.NotEq(ContentState.Deleted)
                .Select<PartProductGoogleModel>();//.Take<PartProductGoogleModel>(take200);

            IList<PartProductGoogleModel> ret = (from x in cmlist
                                                        where 

                                                         x.Brand.Contains(text)
                                                        || x.CurrentPrice.Contains(text)
                                                        || x.Description.Contains(text)
                                                        || x.Gname.Contains(text)
                                                        || x.Identifier.Contains(text)
                                                        || (x.Parent.Title!=null && x.Parent.Title.Contains(text))
                                                        select x).ToList();
            return ret;
        }

        [ContentOutputCache]
        public ActionResult Translations(int id)
        {
            StringBuilder sb = new StringBuilder();

            var lg = Engine.Resolve<ILanguageGateway>();
            var translations = lg.FindTranslations(Engine.Persister.Get(id));
            foreach (var language in translations)
                sb.Append("<li>").Append(Link.To(language).Text(lg.GetLanguage(language).LanguageTitle)).Append("</li>");

            if (sb.Length == 0)
                return Content("<ul><li>This page is not translated</li></ul>");

            return Content("<ul>" + sb + "</ul>");
        }
    }
}
